package com.ikas.ai.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/***
 * @description redis操作工具类
 * @author deng.baohui
 * @date 2021/11/19 18:59
 */
@SuppressWarnings("all")
@Component
@Slf4j
public class RedisUtil {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 获取有序set集合操作
     *
     * @return
     */
    public ZSetOperations getZSetOperations() {
        ZSetOperations<String, Object> zSetOperations = redisTemplate.opsForZSet();
        return zSetOperations;
    }

    public ValueOperations getValueOperations() {
        ValueOperations<String, Object> options = redisTemplate.opsForValue();
        return options;
    }

    public HashOperations getHashOperations() {
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        return hashOperations;
    }

    public ListOperations getListOperations() {
        ListOperations<String, Object> listOperations = redisTemplate.opsForList();
        return listOperations;
    }

    /**
     * 获取无序set集合操作
     *
     * @return
     */
    public SetOperations getSetOperations() {
        SetOperations<String, Object> setOperations = redisTemplate.opsForSet();
        return setOperations;
    }

    /***
     * Hash结构保存数据
     * @param key hash唯一性
     * @param hashKey 业务实体ID
     * @param value 业务实体值
     */
    public void hashSave(String key, String hashKey, String value) {
        redisTemplate.opsForHash().put(key, hashKey, value);
    }

    /***
     * Hash结构获取数据
     * @param key hash唯一性
     * @param hashKey 业务实体ID
     * @return
     */
    public Object hashGet(String key, String hashKey) {
        return getHashOperations().get(key, hashKey);
    }

    /***
     * Hash结构转换为Map
     * @param key hash唯一性
     * @return
     */
    public Map hashToMap(String key) {
        return getHashOperations().entries(key);
    }

    /***
     * Hash结构删除数据
     * @param key hash唯一性
     * @param hashKey 业务实体ID
     */
    public void hashDelete(String key, String hashKey) {
        getHashOperations().delete(key, hashKey);
    }

    /***
     * 根据key删除
     * @param key
     */
    public void deleteKey(String key) {
        redisTemplate.delete(key);
    }

    /***
     * 保存字符串信息
     * @param key
     * @param value
     */
    public void stringSave(String key, String value) {
        getValueOperations().set(key, value);
    }

    /**
     * 一定实效保存字符串
     *
     * @param key
     * @param value
     * @param expire
     * @param timeUnit
     */
    public void stringSave(String key, String value, long expire, TimeUnit timeUnit) {
        getValueOperations().set(key, value, expire, timeUnit);
    }

    /***
     * 获取字符串
     * @param key
     * @return
     */
    public String stringGet(String key) {
        if (Objects.isNull(getValueOperations())) {
            return "";
        }
        Object value = getValueOperations().get(key);
        if (Objects.isNull(value)) {
            return "";
        }
        return value.toString();
    }

    /***
     * 是否存在该Key
     * @param key
     * @return
     */
    public boolean haskey(String key) {
        return redisTemplate.hasKey(key);
    }

    /***
     * 将value存储到List中
     * @param key
     * @param value
     */
    public void listLeftPush(String key, String value) {
        getListOperations().leftPush(key, value);
    }

    /***
     * 从List的右侧弹出vlaue
     * @param key
     * @return
     */
    public String listRightPop(String key) {
        return getListOperations().rightPop(key) != null ? getListOperations().rightPop(key).toString() : "";
    }

    /***
     * list中个数
     * @param key
     * @return
     */
    public long llen(String key) {
        return getListOperations().size(key);
    }

    /***
     * 从List集合左侧弹出
     * @param key
     * @return
     */
    public String lpop(String key) {
        return getListOperations().leftPop(key) != null ? getListOperations().leftPop(key).toString() : "";
    }

    /***
     * 存储一个或多个元素到Set集合中
     * @param key
     * @param value
     */
    public void setAdd(String key, String... value) {
        getSetOperations().add(key, value);
    }


    /***
     * 判断元素是否存在Set集合中
     * @param key
     * @param value
     * @return
     */
    public boolean setIsMember(String key, String value) {
        return getSetOperations().isMember(key, value);
    }


    /**
     * 保存复杂类型数据到缓存
     *
     * @param key
     * @param obj
     * @return
     */
    public void saveBean(String key, Object obj) {
        redisTemplate.opsForValue().set(key, JSON.toJSONString(obj));
    }

    /**
     * 保存复杂类型数据到缓存（并设置失效时间）
     *
     * @param key
     * @param obj
     * @param seconds
     */
    public void saveBean(String key, Object obj, int seconds) {
        redisTemplate.opsForValue().set(key, JSON.toJSONString(obj), seconds, TimeUnit.SECONDS);
    }

    /**
     * 保存redis数组对象
     *
     * @param key
     * @param arrBean
     * @return
     */
    public void saveArrBean(String key, Object arrBean) {
        redisTemplate.opsForValue().set(key, JSONArray.toJSONString(arrBean));
    }

    /**
     * 保存redis数组对象（并设置失效时间）
     *
     * @param key
     * @param obj
     * @param seconds
     */
    public void saveArrBean(String key, Object obj, int seconds) {
        redisTemplate.opsForValue().set(key, JSONArray.toJSONString(obj), seconds, TimeUnit.SECONDS);
    }

    /**
     * 取得复杂JSON数据
     *
     * @param key
     * @param clazz
     * @param clazz
     * @return
     */
    public <T> T getBean(String key, Class<T> clazz) {
        Object value = getValueOperations().get(key);
        if (value == null) {
            return null;
        }
        return JSON.parseObject(value.toString(), clazz);
    }

    /**
     * 获取redis JSONObject对象
     *
     * @param key
     * @return
     */
    public JSONObject getBean(String key) {
        Object value = getValueOperations().get(key);
        if (value == null) {
            return null;
        }
        return JSON.parseObject(value.toString());
    }

    /**
     * 获取redis数组对象-JSONArray
     *
     * @param key
     * @return
     */
    public JSONArray getArrBean(String key) {
        Object value = getValueOperations().get(key);
        if (value == null) {
            return null;
        }
        JSONArray jsonArray = JSONArray.parseArray(value.toString());
        return jsonArray;
    }

    /**
     * 获取redis数组对象
     *
     * @param key
     * @return
     */
    public <T> List<T> getArrBean(String key, Class<T> clazz) {
        Object value = getValueOperations().get(key);
        if (value == null) {
            return null;
        }
        List<T> list = JSONArray.parseArray(value.toString(), clazz);
        return list;
    }

    /**
     * 获取存活时间
     *
     * @param key
     * @return
     */
    public long ttl(String key) {
        return redisTemplate.getExpire(key);
    }
}
